
package com.yadong.smarthome2.ui;

import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.app.Dialog;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnDismissListener;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.ListView;
import android.widget.Toast;

import com.yadong.smarthome2.R;
import com.yadong.smarthome2.device.Device;
import com.yadong.smarthome2.device.Device.DeviceState;
import com.yadong.smarthome2.device.DeviceManagerService;
import com.yadong.smarthome2.device.DeviceManagerService.MyBinder;
import com.yadong.smarthome2.devicefinder.DeviceFinderWorker.ScanListener;
import com.yadong.smarthome2.devicefinder.DeviceListener;
import com.yadong.smarthome2.devicefinder.DeviceStatusListener;
import com.yadong.smarthome2.protocol2.RequestProtocol.Parameter;
import com.yadong.smarthome2.protocol2.RequestProtocol.Request;
import com.yadong.smarthome2.protocol2.ResultProtocol.Function;

public class ScanDeviceActivity extends Activity
        implements DeviceListener, ScanListener, OnItemClickListener,
        DeviceStatusListener, OnItemLongClickListener {
    private static final int MSG_DEVICE_FINDED = 1;
    private static final int MSG_DEVICE_STATUS_CHANGED = 2;
    private DeviceListAdapter mListAdapter;
    private FunctionListAdapter mFunctionAdapter;
    private DeviceManagerService mDeviceManager;
    private Device mConnectedDevice = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Intent intent = new Intent(ScanDeviceActivity.this, DeviceManagerService.class);
        bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);
        mListAdapter = new DeviceListAdapter(this);
        mFunctionAdapter = new FunctionListAdapter(this);

        ListView list = (ListView) findViewById(R.id.list_devices);
        list.setAdapter(mListAdapter);
        list.setOnItemLongClickListener(this);
        list.setOnItemClickListener(this);

        ListView functionList = (ListView) findViewById(R.id.list_functions);
        functionList.setAdapter(mFunctionAdapter);
        functionList.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> arg0, View arg1, int position, long arg3) {
                Function function = (Function) mFunctionAdapter.getItem(position);
                final Request.Builder builder = Request.newBuilder();
                builder.setTime(System.currentTimeMillis());
                builder.setTag(function.getCode());

                if (function.getArgumentsCount() <= 0) {
                    // no argument means is a message to this
                    mDeviceManager.sendData(mConnectedDevice, builder.build());
                } else {
                    final InputParameterDialogBuilder inputParameterDialogBuilder =
                            new InputParameterDialogBuilder(ScanDeviceActivity.this);
                    Dialog dialog = inputParameterDialogBuilder
                            .createInputDailog(function.getArgumentsList());
                    dialog.setOnDismissListener(new OnDismissListener() {
                        @Override
                        public void onDismiss(DialogInterface arg0) {
                            mParameters = inputParameterDialogBuilder.getAllParameters();
                            if (mParameters != null) {
                                builder.addAllParameters(mParameters);
                            }
                            mDeviceManager.sendData(mConnectedDevice, builder.build());
                        }
                    });
                    dialog.show();
                }
            }
        });

        findViewById(R.id.btn_scan).setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {
                mDeviceManager.startFindDevice(ScanDeviceActivity.this,
                        ScanDeviceActivity.this);
            }
        });
    }

    private ServiceConnection mServiceConnection = new ServiceConnection() {
        @Override
        public void onServiceDisconnected(ComponentName name) {
            
        }
        @Override
        public void onServiceConnected(ComponentName name, IBinder binder) {
            mDeviceManager = ((MyBinder)binder).getService();
            mDeviceManager.addDeviceStatusListener(ScanDeviceActivity.this);
        }
    };

    private List<Parameter> mParameters;

    

    @Override
    protected void onStart() {
        super.onStart();
    }

    @Override
    protected void onStop() {
        super.onStop();
        mDeviceManager.stopFindDevice();
        mDeviceManager.removeDeviceStatusListener(this);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unbindService(mServiceConnection);
    }

    @Override
    public void onScanStart() {
        Toast.makeText(this, "on Scan Start", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onScanEnded() {
        Toast.makeText(this, "on Scan Ended", Toast.LENGTH_SHORT).show();
    }

    

    private Handler mHandler = new Handler() {
        public void handleMessage(android.os.Message msg) {
            switch (msg.what) {
                case MSG_DEVICE_FINDED:
                    mListAdapter.setDevices(mDeviceManager.getFindedDevice());
                    break;
                case MSG_DEVICE_STATUS_CHANGED:
                    mListAdapter.notifyDataSetChanged();
                    Device changed = (Device) msg.obj;
                    if (changed.getState() == DeviceState.FUNCIONLOADED) {
                        mFunctionAdapter.setFunctions(changed.getFunctions());
                    } else if (changed.getState() == DeviceState.PAIRED) {
                        mFunctionAdapter.setFunctions(new ArrayList<Function>());
                    }
                    break;
                default:
                    break;
            }
        };
    };

    @Override
    public void onDeviceFinded(Device device) {
        Message message = mHandler.obtainMessage(MSG_DEVICE_FINDED);
        message.sendToTarget();
    }

    @Override
    public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
        Device device = (Device) mListAdapter.getItem(position);
        mDeviceManager.connectDevice(device);
    }

    @Override
    public void onDeviceStatusChanged(DeviceState oldState, Device changedDevice) {
        if (changedDevice.getState() == DeviceState.CONNECTED) {
            mConnectedDevice = changedDevice;
        } else if (changedDevice.getState() == DeviceState.PAIRED) {
            mConnectedDevice = null;
        }
        Message message = mHandler.obtainMessage(MSG_DEVICE_STATUS_CHANGED);
        message.obj = changedDevice;
        message.sendToTarget();
    }

    @Override
    public boolean onItemLongClick(AdapterView<?> arg0, View arg1, int position, long arg3) {
        Device device = (Device) mListAdapter.getItem(position);
        mDeviceManager.disconnectDevice(device);
        return true;
    }

}
